#include<iostream>
using namespace std;

#define MAX_INPUT_STR_LEN 101
#define MAX_STR_LEN 17

#define DEBUG_MOD
#ifdef DEBUG_MOD
#define NODE_INFORM_OUPUT(inform)   cout << inform << ' ' << __LINE__ << ": " << endl << "inputStr: ";  \
                                for(char* p = this->pathName; *p != 0; p++) cout << *p;              \
                                cout << endl << "fileName: ";                                        \
                                for(char* p = this->fileName; *p != 0; p++) cout << *p;              \
                                cout << ' ' << this->line << endl << endl
#define LOG(str) cout << __LINE__ << ": " << str << endl
#else
#define NODE_INFORM_OUPUT(inform)
#define LOG(str)
#endif //DEBUG_MOD

struct Node
{
    static uint16_t objCounst;
    static Node* head;
    static Node* outputHead;

    char* pathName = nullptr;
    char fileName[MAX_STR_LEN] = {0};
    uint16_t line = 0;
    uint16_t sameCounst = 0;
    Node* next = nullptr;
    
    bool isFileNameEqual(Node* otherNode)
    {
        int i = 0;
        for( ; (this->fileName[i] != 0) && (otherNode->fileName[i] != 0); i++)
        {
            if(this->fileName[i] != otherNode->fileName[i])
            {
                return false;
            }
        } // 出现this与other 其一 或 两者都 出现 为零 ，则跳出for
        if((this->fileName[i] != 0) || (otherNode->fileName[i] != 0)) // 有一个不为0，即不是两个都为0，则返回false
        {
            return false;
        }
        return true;
    }
    
    bool isPathNameEqual(Node* otherNode)
    {
        int i = 0;
        for( ; (this->pathName[i] != 0) && (otherNode->pathName[i] != 0); i++)
        {
            if(this->pathName[i] != otherNode->pathName[i])
            {
                return false;
            }
        } // 出现this与other 其一 或 两者都 出现 为零 ，则跳出for
        if((this->pathName[i] != 0) || (otherNode->pathName[i] != 0)) // 有一个不为0，即不是两个都为0，则返回false
        {
            return false;
        }
        return true;
    }
    
    Node(char* inStr, uint16_t inLine)
    {
        char* p = nullptr;
        for(p = inStr + (MAX_INPUT_STR_LEN-1); *p == 0; p--);
        char* inStrEnd = p;
        uint16_t inStrLen = p - inStr + 1;
        this->pathName = new char[inStrLen + 1]{0};
        for(int i = 0; inStr[i] != 0; i++)
        {
            this->pathName[i] = inStr[i];
        }
        
        
        uint16_t lenCounst = 1;
        for( ; (*p != '\\') && (lenCounst < MAX_STR_LEN); p--)
        {
            lenCounst++;
        }
        p++;
        for(char* pthisStr = this->fileName ; *p != 0; )
        {
            *pthisStr = *p;
            pthisStr++;
            p++;
        }
        
        this->line = inLine;
        this->sameCounst++;
        NODE_INFORM_OUPUT("Node build");
    }
    
    void addNew(Node* newNode, Node* lastNode = nullptr)
    {
        if(newNode->line != this->line)
        {
            if(this->next == nullptr)
            {
                if(Node::objCounst < 8)
                {
                    Node::objCounst++;
                    this->next = newNode;
                    LOG("line不等，未满8个，塞到末尾");
                    return;
                }
                else
                {
                    this->next = newNode;

                    Node* tmpHead = Node::head;
                    Node::head = Node::head->next;
                    delete tmpHead;
                    LOG("line不等，满8个，塞到末尾，并删除head");
                    return;
                }
            }
            else // if(this->next != nullptr)
            {
                LOG("line不等，跳转到下一个Node");
                this->next->addNew(newNode);
            }
        }
        else // if(newNode->line == this->line)
        {
            bool isEqual_A = this->isFileNameEqual(newNode);
            if(isEqual_A)
            {
                bool isEqual_B = this->isPathNameEqual(newNode);
                if(isEqual_B)
                {
                    LOG("line、fileName、pathName都同，忽略");
                    return;
                }
                else
                {
                    LOG("line、fileName相同，count加1");
                    this->sameCounst++;
                    return;
                }
            }
            else
            {
                LOG("line相等，但fileName不相等,跳到下一个Node");
                this->next->addNew(newNode);
            }
        }
    }
    
    void outputResult()
    {
        for(char* p = this->fileName; *p != 0; p++) cout << *p;
        cout << ' ' << this->line << ' ' << this->sameCounst << endl;
        
        if(this->next != nullptr)
        {
            this->next->outputResult();
        }
    }
};

uint16_t Node::objCounst = 0;
Node* Node::head = nullptr;
Node* Node::outputHead = nullptr;

int main()
{
    char* inputStr = new char[MAX_INPUT_STR_LEN]{0};
    for(; cin >> inputStr; )
    {
        uint16_t inputLine;
        cin >> inputLine;
        
        Node* newNode = new Node(inputStr, inputLine);
        delete inputStr;
        inputStr = new char[MAX_INPUT_STR_LEN]{0};
        if(Node::head == nullptr)
        {
            Node::head = newNode;
            Node::objCounst++;
        }else{
            Node::head->addNew(newNode);
        }
    }

    Node::head->outputResult();
    
    return 0;
}